﻿using System.Collections.Generic;
using System.Linq;
using MIAP.DataAccess.Interfaces;
using MIAP.DataAccess.SqlServer.Model;
using MIAP.Entidades;
using MIAP.Entidades.Enums;

namespace MIAP.DataAccess.Implementaciones.SQL
{
    /// <summary>
    /// Clase para el acceso a datos para la vista Consulta Cargas y Ejecución de Proyectos.
    /// </summary>
    public class ConsultaCargasEjecucionProyectoDao : IConsultaCargasEjecucionProyectoDao
    {
        /// <summary>
        /// Obtiene los tipos de proceso relacionados con las cargas y recargas de archivos y ejecución y reejecución de proyectos. 
        /// </summary>
        /// <returns></returns>
        public IList<CatalogoInfo> GetTipoProceso()
        {
            List<CatalogoInfo> result;

            using (var context = new MIAPDBEntities())
            {
                var query = from tipoProceso in context.MIAP_TIPO_PROCESO
                            where tipoProceso.ID_TIPO_PROCESO == (int)TipoProceso.Carga || tipoProceso.ID_TIPO_PROCESO == (int)TipoProceso.Recarga
                            || tipoProceso.ID_TIPO_PROCESO == (int)TipoProceso.Ejecucion
                            select new CatalogoInfo()
                            {
                                IdItem = tipoProceso.ID_TIPO_PROCESO,
                                Descripcion = tipoProceso.NOMBRE
                            };

                result = query.ToList();
            }

            return result;
        }

        /// <summary>
        /// Obtiene todas las cargas, recargas de un archivo.
        /// </summary>
        /// <param name="consultaCargaFilters">Filtros.</param>
        /// <returns>Lista de los archivos con cargas y recargas de acuerdo a los filtros.</returns>
        public IList<ConsultaCargaEjecucionInfo> GetCargasArchivos(ConsultaCargaEjecucionInfo consultaCargaFilters)
        {
            List<ConsultaCargaEjecucionInfo> result;

            using (var context = new MIAPDBEntities())
            {
                var query = from cargaArchivo in context.MIAP_CARGA_ARCHIVO
                            join bitacoraGeneralCargaArchivo in context.MIAP_BITACORA_GENERAL_CARGA_ARCHIVO
                            on cargaArchivo.ID_CARGA_ARCHIVO equals bitacoraGeneralCargaArchivo.ID_CARGA_ARCHIVO
                            join bitacoraGeneral in context.MIAP_BITACORA_GENERAL
                            on bitacoraGeneralCargaArchivo.ID_BITACORA_GENERAL equals bitacoraGeneral.ID_BITACORA_GENERAL
                            join bitacoraArchivo in context.MIAP_BITACORA_ARCHIVO
                            on bitacoraGeneral.ID_BITACORA_GENERAL equals bitacoraArchivo.ID_BITACORA_GENERAL
                            join archivo in context.MIAP_ARCHIVO
                            on bitacoraArchivo.ID_ARCHIVO equals archivo.ID_ARCHIVO
                            join proyecto in context.MIAP_PROYECTO
                            on archivo.ID_PROYECTO equals proyecto.ID_PROYECTO
                            where (((!consultaCargaFilters.IdTipoProceso.HasValue || consultaCargaFilters.IdTipoProceso == bitacoraGeneral.ID_TIPO_PROCESO) 
                            || (!consultaCargaFilters.IdTipoProceso.HasValue && bitacoraGeneral.ID_TIPO_PROCESO == (int)TipoProceso.Carga)
                            || (!consultaCargaFilters.IdTipoProceso.HasValue && bitacoraGeneral.ID_TIPO_PROCESO == (int)TipoProceso.Recarga) 
                            || (!consultaCargaFilters.IdTipoProceso.HasValue && bitacoraGeneral.ID_TIPO_PROCESO == (int)TipoProceso.Ejecucion))
                            && (!consultaCargaFilters.IdProyecto.HasValue || archivo.ID_PROYECTO == consultaCargaFilters.IdProyecto)
                            && (!consultaCargaFilters.IdArchivo.HasValue || bitacoraArchivo.ID_ARCHIVO == consultaCargaFilters.IdArchivo)
                            && (!consultaCargaFilters.IdUsuario.HasValue || bitacoraGeneral.ID_USUARIO == consultaCargaFilters.IdUsuario)
                            && (!consultaCargaFilters.Año.HasValue || bitacoraGeneral.AÑO == consultaCargaFilters.Año)
                            && (!consultaCargaFilters.Mes.HasValue || bitacoraGeneral.MES == consultaCargaFilters.Mes)
                            && (bitacoraGeneral.ID_ESTATUS_PROCESO == (int)EstatusProceso.Finalizado_Correcto))
                            select new ConsultaCargaEjecucionInfo()
                            {
                                IdBitacora = bitacoraGeneral.ID_BITACORA_GENERAL,
                                IdCargaArchivo = cargaArchivo.ID_CARGA_ARCHIVO,                                
                                IdProyecto = proyecto.ID_PROYECTO,
                                IdArchivo = archivo.ID_ARCHIVO,
                                NombreProyecto = proyecto.NOMBRE,
                                NombreArchivo = archivo.NOMBRE,
                                TipoProceso = bitacoraGeneral.MIAP_TIPO_PROCESO.NOMBRE,
                                FechaProceso = bitacoraArchivo.FECHA_CREACION,
                                Año = bitacoraGeneral.AÑO,
                                Mes = bitacoraGeneral.MES,                                
                                Version = bitacoraArchivo.VERSION,
                                VersionValida = cargaArchivo.VERSION_VALIDA == true ? "SI" : ""
                            };

                result = query.ToList();
            }

            return result;
        }

        /// <summary>
        /// Obtiene las ejecuciones y reejecuciones de un proyecto.
        /// </summary>
        /// <param name="consultaCargaFilters">Filtros.</param>
        /// <returns>Lista de los proyectos ejecutados y reejecutados de acuerdo a los filtros.</returns>
        public IList<ConsultaCargaEjecucionInfo> GetEjecucionProyectos(ConsultaCargaEjecucionInfo consultaCargaFilters)
        {
            List<ConsultaCargaEjecucionInfo> result;

            using (var context = new MIAPDBEntities())
            {
                var query = from bitacoraGeneral in context.MIAP_BITACORA_GENERAL                            
                            join bitacoraProyecto in context.MIAP_BITACORA_PROYECTO
                            on bitacoraGeneral.ID_BITACORA_GENERAL equals bitacoraProyecto.ID_BITACORA_GENERAL
                            join proyecto in context.MIAP_PROYECTO
                            on bitacoraProyecto.ID_PROYECTO equals proyecto.ID_PROYECTO
                            join tipoProceso in context.MIAP_TIPO_PROCESO
                            on bitacoraGeneral.ID_TIPO_PROCESO equals tipoProceso.ID_TIPO_PROCESO
                            where ((bitacoraGeneral.ID_TIPO_PROCESO == (int)TipoProceso.Ejecucion)
                            && (!consultaCargaFilters.IdProyecto.HasValue || bitacoraProyecto.ID_PROYECTO == consultaCargaFilters.IdProyecto)
                            && (!consultaCargaFilters.IdUsuario.HasValue || bitacoraGeneral.ID_USUARIO == consultaCargaFilters.IdUsuario)
                            && (!consultaCargaFilters.Año.HasValue || bitacoraGeneral.AÑO == consultaCargaFilters.Año)
                            && (!consultaCargaFilters.Mes.HasValue || bitacoraGeneral.MES == consultaCargaFilters.Mes)
                            && (!consultaCargaFilters.IdTipoProceso.HasValue || bitacoraGeneral.ID_TIPO_PROCESO == consultaCargaFilters.IdTipoProceso)
                            && (bitacoraGeneral.ID_ESTATUS_PROCESO == (int)EstatusProceso.Finalizado_Correcto))
                            select new ConsultaCargaEjecucionInfo()
                            {
                                IdBitacora = bitacoraGeneral.ID_BITACORA_GENERAL,   
                                IdBitacoraProyecto = bitacoraProyecto.ID_BITACORA_PROYECTO,
                                IdProyecto = proyecto.ID_PROYECTO,
                                NombreProyecto = proyecto.NOMBRE,   
                                FechaProceso = bitacoraProyecto.FECHA_CREACION,
                                Año = bitacoraGeneral.AÑO,
                                Mes = bitacoraGeneral.MES,
                                TipoProceso = tipoProceso.NOMBRE,                               
                            };

                result = query.ToList();
            }

            return result;
        }

        /// <summary>
        /// Obtiene el autorizador de la recarga del archivo.
        /// </summary>
        /// <param name="listArchivos">Lista de archivos.</param>
        /// <returns>Lista con los nombres de los autorizadores.</returns>
        public IList<EjecutorInfo> GetAutorizadorArchivos(List<EjecutorInfo> listArchivos)
        {
            List<EjecutorInfo> listAutorizadores = new List<EjecutorInfo>(); ;

            using (var context = new MIAPDBEntities())
            {
                foreach (EjecutorInfo archivo in listArchivos)
                {
                    var query = from usuario in context.usp_ObtenDatosUsuarioSistema(null, null)
                                join bitacoraGeneral in context.MIAP_BITACORA_GENERAL
                                on usuario.ID_USUARIO equals bitacoraGeneral.ID_USUARIO
                                join bitacoraArchivo in context.MIAP_BITACORA_ARCHIVO
                                on bitacoraGeneral.ID_BITACORA_GENERAL equals bitacoraArchivo.ID_BITACORA_GENERAL
                                join bitacoraGeneralCargaArchivo in context.MIAP_BITACORA_GENERAL_CARGA_ARCHIVO
                                on bitacoraGeneral.ID_BITACORA_GENERAL equals bitacoraGeneralCargaArchivo.ID_BITACORA_GENERAL
                                where (bitacoraGeneralCargaArchivo.ID_CARGA_ARCHIVO == archivo.IdCargaArchivo
                                && bitacoraArchivo.VERSION == archivo.VersionArchivo
                                && bitacoraGeneral.ID_BITACORA_GENERAL == archivo.IdBitacora
                                && (bitacoraGeneral.ID_TIPO_PROCESO == (int)TipoProceso.Recarga))                                
                                select new EjecutorInfo
                                {
                                    IdBitacora = archivo.IdBitacora,
                                    IdCargaArchivo = archivo.IdCargaArchivo,
                                    NombreEjecutor = usuario.Nombre + " " + usuario.ApellidoPaterno + " " + usuario.ApellidoMaterno,
                                    VersionArchivo = archivo.VersionArchivo
                                };

                    EjecutorInfo autorizador = query.OrderByDescending(p => p.FechaProceso).FirstOrDefault();

                    if (autorizador != null)
                    {
                        listAutorizadores.Add(autorizador);
                    }
                }
            }

            return listAutorizadores;
        }

        /// <summary>
        /// Obtiene el autorizador de la ejecución o reejecución del proyecto.
        /// </summary>
        /// <param name="listProyectos">Lista de proyectos.</param>
        /// <returns>Lista con los nombres de los autorizadores.</returns>
        public IList<EjecutorInfo> GetAutorizadorProyectos(List<EjecutorInfo> listProyectos)
        {
            List<EjecutorInfo> listAutorizadores = new List<EjecutorInfo>(); ;

            using (var context = new MIAPDBEntities())
            {
                foreach (EjecutorInfo proyecto in listProyectos)
                {
                    var query = from usuario in context.usp_ObtenDatosUsuarioSistema(null, null)
                                join bitacoraGeneral in context.MIAP_BITACORA_GENERAL
                                on usuario.ID_USUARIO equals bitacoraGeneral.ID_USUARIO
                                join bitacoraProyecto in context.MIAP_BITACORA_PROYECTO
                                on bitacoraGeneral.ID_BITACORA_GENERAL equals bitacoraProyecto.ID_BITACORA_GENERAL                               
                                where (bitacoraProyecto.ID_BITACORA_PROYECTO == proyecto.IdBitacoraProyecto                               
                                && bitacoraProyecto.ID_BITACORA_GENERAL == proyecto.IdBitacora
                                && (bitacoraGeneral.ID_TIPO_PROCESO == (int)TipoProceso.Recarga))
                                select new EjecutorInfo
                                {
                                    IdBitacora = proyecto.IdBitacora,   
                                    IdBitacoraProyecto = proyecto.IdBitacoraProyecto,
                                    NombreEjecutor = usuario.Nombre + " " + usuario.ApellidoPaterno + " " + usuario.ApellidoMaterno                                    
                                };

                    EjecutorInfo autorizador = query.OrderByDescending(p => p.FechaProceso).FirstOrDefault();

                    if (autorizador != null)
                    {
                        listAutorizadores.Add(autorizador);
                    }
                }
            }

            return listAutorizadores;
        }

        /// <summary>
        /// Obtiene el nombre del versionador de la carga o recarga del archivo.
        /// </summary>
        /// <param name="listArchivosProyectos">Lista de archivos versionables.</param>
        /// <returns>Lista de ids de archivos y sus respectivos versionadores.</returns>
        public IList<EjecutorInfo> GetNombreVersionador(List<EjecutorInfo> listArchivosProyectos)
        {
            IList<EjecutorInfo> result = new List<EjecutorInfo>();

            EjecutorInfo versionador = new EjecutorInfo();

            using (var context = new MIAPDBEntities())
            {
                foreach (EjecutorInfo archivoProyecto in listArchivosProyectos)
                {
                    var query = (from usuario in context.usp_ObtenDatosUsuarioSistema(null, null)
                                 join bitacoraGeneral in context.MIAP_BITACORA_GENERAL
                                 on usuario.ID_USUARIO equals bitacoraGeneral.ID_USUARIO                                
                                 where (bitacoraGeneral.ID_BITACORA_GENERAL == archivoProyecto.IdBitacora)                                
                                 select new EjecutorInfo()
                                 {
                                     IdBitacora = archivoProyecto.IdBitacora,                                    
                                     NombreEjecutor = string.Format("{0}{1}{2}{3}{4}", usuario.Nombre, " ", usuario.ApellidoPaterno, " ", usuario.ApellidoMaterno)
                                 }).Distinct();

                    versionador = query.First();

                    result.Add(versionador);
                }
            }

            return result;
        }
    }
}
